/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package elevatronic.models;

import elevatronic.utils.Utils;
import elevatronic.utils.Utils.Direction;

import java.util.ArrayList;
import java.util.List;
import pl.gdan.elsy.tool.Rand;

/**
 * 
 * @author Exosta
 */
public class Building {
    
    // Distance between two floors, stated in meters
    public static final double DISTANCE_FLOORS = 3.0;
    
    List<Floor> floors;
    List<Elevator> elevators;

    public List<Floor> getFloors() {
        return floors;
    }

    public void setFloors(List<Floor> floors) {
        this.floors = floors;
    }

    public List<Elevator> getElevators() {
        return elevators;
    }

    public void setElevators(List<Elevator> elevators) {
        this.elevators = elevators;
    }
    
    
    //average waiting time of every people, used to know the improvement of the IA
    public int getAverageWaitingTime(){
    	//TODO Guillaume, please fill this method please
    	return 1000;
    }
    
    
    /**
     * Constructor
     */
    public Building(){
        setFloors(new ArrayList<Floor>());	        
        setElevators(new ArrayList<Elevator>());
        for(int i=0;i<10;i++){
	        getFloors().add(new Floor(i));	        	
        }
        for(int i=0;i<4;i++){
	        getElevators().add(new Elevator(i));	        	
        }
    }
    
    /**
     * Method which manage people on the building (Random arrivals, moving people...)
     * @param step 
     */
    public void update(int step) {
        spawningPeople();
        
        // Managing elevators
        for (int i = 0; i < this.elevators.size(); i++) {
            this.elevators.get(i).setCurrentStep(this.elevators.get(i).getCurrentStep() + 1);
            this.elevators.get(i).setRemainingTime(this.elevators.get(i).getRemainingTime() - (int)(1 / Elevator.SPEED));
            // Using steps, speed and direction to know where is the elevator
            if (this.elevators.get(i).getCurrentStep() >= 1/Elevator.SPEED)
                if (this.elevators.get(i).getDirection() == Direction.DESCENDING)
                    this.elevators.get(i).setCurrentFloor(this.elevators.get(i).getCurrentFloor() - 1);
                else if (this.elevators.get(i).getDirection() == Direction.ASCENDING) {
                    this.elevators.get(i).setCurrentFloor(this.elevators.get(i).getCurrentFloor() + 1);
            }
        }
        
        
        // Managing People
    }
    
    private void spawningPeople() {
        // TODO Guillaume : Improve random function doing a lot of arrivals rare
        for (Floor floor : this.floors) {
            if (Rand.i(0, 10) == 0) {
                int peopleOnTheFLoor = Rand.i(0, 3);
                if(peopleOnTheFLoor != 0) {
                    for (int i = 0; i < peopleOnTheFLoor; i++) {
                            //TODO Guillaume, it has to success normaly plz
                            //<a corriger>
                        int endingPoint;
                                            try {
                                                    endingPoint = Utils.RandomWithoutAValue(1, 10, floor.getNumber());
                                            } catch (Exception e) {
                                                    endingPoint=0;
                                            }
                                            //</a corriger>
                        People people = new People(floor.getNumber(), endingPoint);
                        if (endingPoint < floor.getNumber())
                            floor.getButtonDown().setPushed(true);
                        else
                            floor.getButtonUp().setPushed(true);
                        floor.addPeople(people);
                        choiceElevators(endingPoint);
                    }
                }
            }
        }
    }
    
    private void choiceElevators(int targetFloor) {
        // TODO Improve selecting elevators
        int choiceElevator = Rand.i(0,4);
        Elevator elevator = this.elevators.get(choiceElevator);
        this.elevators.get(choiceElevator).setTargettedFloor(targetFloor);
        this.elevators.get(choiceElevator).setTimeToMakeTheTrip(Math.abs(this.elevators.get(choiceElevator).getTargettedFloor() - this.elevators.get(choiceElevator).getCurrentFloor()));
        this.elevators.get(choiceElevator).setRemainingTime(this.elevators.get(choiceElevator).getTimeToMakeTheTrip());
    }
    
    private Floor findFloorByNumber(int floorNumber) {
        for (int i = 0; i < this.floors.size(); i++) {
            if (this.floors.get(i).getNumber() == floorNumber)
                return this.floors.get(i);
        }
        return this.floors.get(0);
    }
    
}
